﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Text.RegularExpressions;
using System.Collections;
using TMHuy.config;
using System.IO;
using System.Windows.Forms.DataVisualization.Charting;
using System.Threading;

namespace TMHuy
{
    public partial class Main : Form
    {

        AllConfig config;
        Travian42 adapter;
        VillageShortInfo[] villages;
        public int[,] attacks;
        bool startPlan = false;
        int n;
        Thread[] threads;
        Hashtable raidLog;
        ArrayList notes;

        public Main()
        {
            InitializeComponent();
        }

        private void updateListViewVillage()
        {
            listViewVillage.Items.Clear();
            comboBoxRouteFrom.Items.Clear();
            comboBoxRouteTo.Items.Clear();
            foreach (Village village in config.villages)
            {
                listViewVillage.Items.Add(new ListViewItem(new string[] { village.name, village.getXY(), village.id.ToString(), village.getNCleanOasis().ToString()+"/"+village.zones.Count.ToString() }));
                comboBoxRouteFrom.Items.Add(village.name);
                comboBoxRouteTo.Items.Add(village.name);
            }
        }

        private void updateListViewRaidLog()
        {
            listViewRaidLog.Items.Clear();
            foreach (string key in raidLog.Keys)
            {
                DateTime time = new DateTime((long)raidLog[key]);
                listViewRaidLog.Items.Add(new ListViewItem(new string[] { key, time.ToString() }));
            }
            foreach (Village village in config.villages)
            {
                listViewVillage.Items.Add(new ListViewItem(new string[] { village.name, village.getXY(), village.id.ToString(), village.getNCleanOasis().ToString() + "/" + village.zones.Count.ToString() }));
                comboBoxRouteFrom.Items.Add(village.name);
                comboBoxRouteTo.Items.Add(village.name);
            }
        }

        private void updateListViewFarmTarget(ArrayList zones)
        {
            listViewFarmTarget.Items.Clear();
            int free = 0;
            foreach (Zone zone in zones)
            {
                listViewFarmTarget.Items.Add(new ListViewItem(new string[] { zone.getXY(), zone.distance.ToString(), new DateTime(zone.lastSend).ToShortTimeString(), zone.type, zone.defend.ToString() }));
                if (zone.defend == 0 || zone.defend == int.MaxValue) free++;
            }
            labelOasisStatistics.Text = "Oasis (free/total): "+free+"/"+zones.Count;
        }

        private void updateListViewTroop(ArrayList troops)
        {
            listViewTroopToNormalFarm.Items.Clear();
            foreach (Troop troop in troops)
            {
                listViewTroopToNormalFarm.Items.Add(new ListViewItem(new string[] { troop.name, troop.number_each_wave.ToString(), troop.xCleanOasis.ToString(), troop.maxPop.ToString() }));
            }
        }

        private void UpdateListViewFarmList()
        {
            listViewFarmlist.Items.Clear();
            foreach (FarmList farmlist in config.farmlists)
            {
                listViewFarmlist.Items.Add(new ListViewItem(new string[] { farmlist.id.ToString(), farmlist.trooptype.ToString(), farmlist.vid.ToString(), farmlist.count.ToString(), farmlist.maxWaves.ToString(), farmlist.maxPopulation.ToString(), new DateTime(farmlist.lastSend).ToShortTimeString(), farmlist.avoidX+","+farmlist.avoidY+","+farmlist.avoidR, farmlist.farmType.ToString() }));
            }
        }

        private void UpdateListViewTaskCheck()
        {
            listViewTaskCheck.Items.Clear();
            foreach (TaskCheck taskCheck in config.taskChecks)
            {
                listViewTaskCheck.Items.Add(new ListViewItem(new string[] { Constants.taskNames[taskCheck.taskType], taskCheck.checkEvery.ToString(), new DateTime(taskCheck.lastDone).ToShortTimeString() }));
            }
        }

        private void UpdateListViewNote()
        {
            listViewNote.Items.Clear();
            foreach (Note note in notes)
            {
                listViewNote.Items.Add(new ListViewItem(new string[] { new DateTime(note.time).ToShortTimeString(), note.message }));
            }
        }

        private void UpdateListViewRoutes()
        {
            listViewRoutes.Items.Clear();
            foreach (Route route in config.routes)
            {
                listViewRoutes.Items.Add(new ListViewItem(new string[] { route.fromName, route.toName, route.getConditionString(), route.getResourceString() }));
            }
        }

        private void UpdateListViewBuildingCurrent(Village village, VillageInfo info)
        {
            listViewBuildingCurrent.Items.Clear();
            ArrayList buildings = new ArrayList();
            foreach (Building building in info.buildable)
            {
                building.queuedLevel = village.getQueuedLevel(building.buildLink, building.level);
                buildings.Add(building);
            }
            foreach (Building building in info.buildings)
            {
                building.queuedLevel = village.getQueuedLevel(building.buildLink, building.level);
                buildings.Add(building);
            }
            foreach (Building building in info.resFields)
            {
                building.queuedLevel = village.getQueuedLevel(building.buildLink, building.level);
                buildings.Add(building);
            }
            buildings.Sort(new BuildingComparer2());
            foreach (Building building in buildings)
            {
                listViewBuildingCurrent.Items.Add(new ListViewItem(new string[] { building.name, building.level.ToString(), building.queuedLevel.ToString(), building.resField.ToString(), building.buildLink }));
            }
            labelEmptySlot.Text = "Empty slots: " + info.emptySlots.Count;
            labelBuidingInProgress.Text = "";
            foreach (BuildingBuilding building in info.inBuilds)
            {
                labelBuidingInProgress.Text += building.name + " level " + building.level + " " + building.timeLeft + "\r\n";
            }
        }

        private void UpdateListViewBuildingQueue(Village village)
        {
            listViewBuildingQueue.Items.Clear();
            foreach (Building building in village.buildingQueues)
            {
                listViewBuildingQueue.Items.Add(new ListViewItem(new string[]{building.name, building.level.ToString()}));
            }
            labelQueueTotal.Text = "Total: " + village.buildingQueues.Count;
        }

        private void UpdateListViewBuyTroop(ArrayList buyTroops)
        {
            listViewBuyTroop.Items.Clear();
            foreach (BuyTroop buyTroop in buyTroops)
            {
                listViewBuyTroop.Items.Add(new ListViewItem(new string[]{buyTroop.buildingName, buyTroop.troopName, buyTroop.maxQueueTime.ToString(), buyTroop.item}));
            }
        }

        private void updateListViewScouts(ArrayList scouts)
        {
            listViewScouts.Items.Clear();
            foreach (Zone scout in scouts)
            {
                listViewScouts.Items.Add(new ListViewItem(new string[] { scout.getXY(), scout.distance.ToString(), new DateTime(scout.lastSend).ToShortTimeString() }));
            }
        }

        private void login()
        {
            if (DateTime.Now.Year <= 2013)
            {
                adapter.username1 = config.account;
                adapter.password1 = config.password;
                adapter.server = config.server;
                adapter.screen = config.screen;

                villages = adapter.login();
                if (villages != null)
                {
                    ArrayList newVillages = new ArrayList();
                    for (int i = 0; i < villages.Length; i++)
                    {
                        bool configured = false;
                        foreach (Village village in config.villages)
                        {
                            if (village.id.Equals(villages[i].id))
                            {
                                village.name = villages[i].name;
                                newVillages.Add(village);
                                configured = true;
                            }
                        }
                        if (!configured)
                        {
                            Village village = new Village();
                            village.name = villages[i].name;
                            village.x = villages[i].x;
                            village.y = villages[i].y;
                            village.id = villages[i].id;
                            newVillages.Add(village);
                        }
                    }
                    config.villages = newVillages;
                }
                if (villages == null)
                {
                    MessageBox.Show("Wrong username/password for main account");
                }
                else
                {
                    this.Text = config.account + "@" + config.server + " - TMHuy version " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString() + " " + Constants.welcomeString;
                    this.notifyIcon1.Text = config.account + "@" + config.server;
                }
                labelTribe.Text = "Tribe: " + Constants.tribeName[Constants.tribe];
                comboBoxTroop.Items.Clear();
                comboBoxTroop.Items.AddRange(Constants.tribeTroop[Constants.tribe]);
                comboBoxTroopBuy.Items.Clear();
                comboBoxTroopBuy.Items.AddRange(Constants.tribeTroop[Constants.tribe]);
                comboBoxTroopTypeToFarmList.Items.Clear();
                comboBoxTroopTypeToFarmList.Items.AddRange(Constants.tribeTroop[Constants.tribe]);
                comboBoxTroopTypeToNormalFarm.Items.Clear();
                comboBoxTroopTypeToNormalFarm.Items.AddRange(Constants.tribeTroop[Constants.tribe]);
                updateListViewVillage();
            }
        }

        private void syncConfigAndForm()
        {
            textBoxAccount.Text = config.account;
            textBoxPassword.Text = config.password;
            textBoxServer.Text = config.server;
            UpdateListViewTaskCheck();
            UpdateListViewFarmList();
            UpdateListViewRoutes();
            textBoxHeroVillageId.Text = config.heroVillageId;
            checkBoxHeroSolo.Checked = config.heroSolo;
            textBoxHeroSoloMinHealth.Text = config.heroSoloMinHealth.ToString();
            textBoxHeroAttackX.Text = config.heroAttackX.ToString();
            checkBoxHeroAdventure.Checked = config.heroAdventure;
            checkBoxHeroClearWithTroop.Checked = config.heroClearWithTroop;
            textBoxHeroClearMinHealth.Text = config.heroClearMinHealth.ToString();
            textBoxHeroTroopAttackX.Text = config.heroTroopAttackX.ToString();
            checkBoxHeroUseInfantryDef.Checked = config.heroUseInfantryDef;
            comboBoxheroTroopType.SelectedItem = config.heroTroopType.id + "_" + config.heroTroopType.name + "_" + config.heroTroopType.attack;
            textBoxRaidInterval.Text = config.raidInterval.ToString();
            textBoxMerchanCapacity.Text = config.merchanCapacity.ToString();
            checkBoxFullMerchan.Checked = config.fullMerchan;
            checkBoxAutoAddFighting.Checked = config.autoAddFighting;
            textBoxScreen.Text = config.screen;
            checkBoxUseTor.Checked = config.useTor;
            Constants.useTor = config.useTor;
        }

        private void Main_Load(object sender, EventArgs e)
        {
            notes = new ArrayList();
            raidLog = new Hashtable();
            comboBoxCheckTasks.Items.AddRange(Constants.taskNames);
            this.Text = "TMHuy version " + System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
            try
            {
                config = Util.DeSerializeConfig("config.xml");
            }
            catch (Exception ex)
            {
                config = new AllConfig();
            }
            ArrayList allOasis = new ArrayList();
            try
            {
                allOasis = Util.DeSerializeArrayList("oasis.xml");
            }
            catch (Exception ex)
            {
            }
            labelTotalOasis.Text = allOasis.Count.ToString() + " oasis in total";
            adapter = new Travian42();
            syncConfigAndForm();
            login();
        }

        private void saveConfig()
        {
            Util.SerializeConfig(config, "config.xml");
        }

        private void buttonLogin_Click(object sender, EventArgs e)
        {
            config.account = textBoxAccount.Text;
            config.password = textBoxPassword.Text;
            config.server = textBoxServer.Text;
            config.screen = textBoxScreen.Text;
            saveConfig();
            login();
        }

        private void buttonSearchAdd_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                ArrayList allOasis = Util.DeSerializeArrayList("oasis.xml");
                for (int i = 0; i < allOasis.Count; i++)
                {
                    Zone zone = (Zone)allOasis[i];
                    zone.distance = Math.Sqrt((zone.x - village.x) * (zone.x - village.x) + (zone.y - village.y) * (zone.y - village.y));
                    double minDist = Convert.ToDouble(textBoxMinDist.Text);
                    double maxDist = Convert.ToDouble(textBoxMaxDist.Text);
                    if (zone.distance > minDist && zone.distance <= maxDist && !village.zones.Contains(zone))
                    {
                        village.zones.Add(zone);
                        zone.defend = int.MaxValue;
                        zone.type = "oasis";
                    }
                }
                village.zones.Sort(new ZoneComparer());
                updateListViewFarmTarget(village.zones);
                saveConfig();
            }
            else
            {
                MessageBox.Show("Please select a village");
            }
        }

        private void buttonLoadAllOasis_Click(object sender, EventArgs e)
        {
            backgroundWorkerLoadAllOasis.RunWorkerAsync();
            buttonReloadAllOasis.Enabled = false;
        }

        private void backgroundWorkerLoadAllOasis_DoWork(object sender, DoWorkEventArgs e)
        {
            ArrayList allOasis = new ArrayList();
            int c = 0;
            for (int ii = -7; ii <= 7; ii++)
                for (int jj = -7; jj <= 7; jj++)
                {
                    int xx = ii * 30 - 15;
                    int yy = jj * 30 - 15;
                    String mapinfo = adapter.postRequestMapInfo(xx.ToString(), yy.ToString());
                    String pattern = "\"x\":\"(-?\\d+)\",\"y\":\"(-?\\d+)\",\"d\":\\-1,\"c\":\"{k.fo}\"";
                    Regex re = new Regex(pattern);
                    MatchCollection matches = re.Matches(mapinfo);
                    for (int i = 0; i < matches.Count; i++)
                    {
                        int x = Convert.ToInt32(matches[i].Groups[1].Value);
                        int y = Convert.ToInt32(matches[i].Groups[2].Value);
                        Zone zone = new Zone();
                        zone.x = x;
                        zone.y = y;
                        allOasis.Add(zone);
                        Console.WriteLine("Added " + zone.x + "," + zone.y);
                    }
                    c++;
                    backgroundWorkerLoadAllOasis.ReportProgress(c * 100 / 15 / 15);
                }
            Util.SerializeArrayList(allOasis, "oasis.xml");
        }

        private void backgroundWorkerLoadAllOasis_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBarLoadAllOasis.Value = e.ProgressPercentage;
        }

        private void backgroundWorkerLoadAllOasis_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            buttonReloadAllOasis.Enabled = true;
            progressBarLoadAllOasis.Value = 0;
            ArrayList allOasis = Util.DeSerializeArrayList("oasis.xml");
            labelTotalOasis.Text = allOasis.Count.ToString() + " oasis in total";
        }

        private void buttonDeleteTarget_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                if (listViewFarmTarget.SelectedItems.Count > 0)
                {
                    village.zones.RemoveAt(listViewFarmTarget.SelectedItems[0].Index);
                    updateListViewFarmTarget(village.zones);
                    saveConfig();
                }
            }
        }

        private void listViewFarmVillage_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                updateListViewFarmTarget(village.zones);
                updateListViewTroop(village.troops);
                UpdateListViewBuyTroop(village.troopToBuy);
                updateListViewScouts(village.scoutTargets);
                if (tabControl1.SelectedTab.Name.Equals("tabPageBuilding"))
                {
                    VillageInfo info = adapter.getVillageInfo(village.id);
                    villages[listViewVillage.SelectedItems[0].Index].detailedInfo = info;
                    UpdateListViewBuildingCurrent(village, villages[listViewVillage.SelectedItems[0].Index].detailedInfo);
                    UpdateListViewBuildingQueue(village);
                }
                checkBoxAutoUpResources.Checked = village.autoUpRes;
                checkBoxAutoParty.Checked = village.autoParty;
            }
        }

        private void buttonDeleteAllTarget_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                village.zones.Clear();
                updateListViewFarmTarget(village.zones);
                saveConfig();
            }
        }


        private void buttonMakeFarmList_Click(object sender, EventArgs e)
        {
            string[] tmp = comboBoxTroopTypeToFarmList.SelectedItem.ToString().Split('_');
            int id = Convert.ToInt32(tmp[0]);
            double n = Convert.ToDouble(textBoxTroopNumberToFarmList.Text);
            bool dynamicNumbering = checkBoxDynamic.Checked;
            int minTroop = Convert.ToInt32(textBoxMinTroopNumber.Text);
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                List<object> arguments = new List<object>();
                arguments.Add(textBoxFarmListAddLink.Text);
                arguments.Add(village.zones);
                arguments.Add(id);
                arguments.Add(n);
                arguments.Add(dynamicNumbering);
                arguments.Add(minTroop);
                backgroundWorkerTransferToFarmlist.RunWorkerAsync(arguments);
                buttonMakeFarmList.Enabled = false;
            }
            else
            {
                MessageBox.Show("Please select a village");
            }
        }

        private void backgroundWorkerTransferToFarmlist_DoWork(object sender, DoWorkEventArgs e)
        {
            List<object> genericlist = e.Argument as List<object>;
            string linkToAdd = (string)genericlist[0];
            Console.WriteLine(linkToAdd);
            ArrayList zones = (ArrayList)genericlist[1];
            Console.WriteLine(zones.Count);
            int id = (int)genericlist[2];
            Console.WriteLine(id);
            double n = (double)genericlist[3];
            Console.WriteLine(n);
            bool dynamicNumbering = (bool)genericlist[4];
            int minTroop = (int)genericlist[5];
            for (int i = 0; i < zones.Count; i++)
            {
                Zone zone = (Zone)zones[i];
                bool added = false;
                int troopToAdd = (int)n;
                if (dynamicNumbering)
                {
                    int pop = adapter.getPop(zone.x, zone.y);
                    if (pop > 0)
                    {
                        troopToAdd = Math.Max(minTroop, pop / 10);
                        added = adapter.addToFarmList(textBoxFarmListAddLink.Text, zone.x, zone.y, id, troopToAdd);
                    }
                    else
                    {
                        Console.WriteLine(zone.x + "," + zone.y + " deleted");
                    }
                }
                else
                {
                    added = adapter.addToFarmList(textBoxFarmListAddLink.Text, zone.x, zone.y, id, troopToAdd);
                }
                backgroundWorkerTransferToFarmlist.ReportProgress(i * 100 / zones.Count);
                Console.WriteLine(zone.distance);
            }
        }

        private void backgroundWorkerTransferToFarmlist_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBarMakeFarmList.Value = e.ProgressPercentage;
        }

        private void backgroundWorkerTransferToFarmlist_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            buttonMakeFarmList.Enabled = true;
            progressBarMakeFarmList.Value = 0;
            MessageBox.Show("Farmlist completed");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show(adapter.scoutable(32, 73).ToString());
        }

        private void buttonAddFarmList_Click(object sender, EventArgs e)
        {
            string[] tmp = comboBoxTroop.SelectedItem.ToString().Split('_');
            FarmList farmlist = new FarmList();
            farmlist.id = Convert.ToInt32(textBoxFLID.Text);
            farmlist.trooptype = tmp[1];
            farmlist.vid = Convert.ToInt32(textBoxVID.Text);
            farmlist.count = 0;
            farmlist.maxWaves = Convert.ToInt32(textBoxMaxWaves.Text);
            farmlist.maxPopulation = Convert.ToInt32(textBoxMaxPop.Text);
            farmlist.avoidX = Convert.ToInt32(textBoxAvoidX.Text);
            farmlist.avoidY = Convert.ToInt32(textBoxAvoidY.Text);
            farmlist.avoidR = Convert.ToDouble(textBoxAvoidRadius.Text);
            farmlist.farmType = Convert.ToInt32(textBoxFarmType.Text);
            config.farmlists.Add(farmlist);
            UpdateListViewFarmList();
            saveConfig();
        }

        private void buttonAddTask_Click(object sender, EventArgs e)
        {
            try
            {
                TaskCheck taskCheck = new TaskCheck();
                taskCheck.taskType = comboBoxCheckTasks.SelectedIndex;
                taskCheck.checkEvery = Convert.ToInt32(textBoxCheckTaskEvery.Text);
                config.taskChecks.Add(taskCheck);
                UpdateListViewTaskCheck();
                saveConfig();
            }
            catch (Exception ex)
            {
            }
        }

        private void buttonDeleteTask_Click(object sender, EventArgs e)
        {
            if (listViewTaskCheck.SelectedItems.Count > 0)
            {
                config.taskChecks.RemoveAt(listViewTaskCheck.SelectedItems[0].Index);
                UpdateListViewTaskCheck();
                saveConfig();
            }
        }

        private void buttonStart_Click(object sender, EventArgs e)
        {
            if (!timer1.Enabled)
            {
                timer1.Start();
                buttonStart.Text = "Stop";
            }
            else
            {
                timer1.Stop();
                buttonStart.Text = "Start";
            }
        }

        long startedOnline = 0;
        long startedOffline = 0;
        int logOutEvery = 7200;
        int logOutFor = 1200;
        bool off = true;
        private void timer1_Tick(object sender, EventArgs e)
        {
            long now = DateTime.Now.Ticks;
            if (off)
            {
                if ((now - startedOffline) / 10000000 > logOutFor)
                {
                    off = false;
                    startedOffline = 0;
                    startedOnline = DateTime.Now.Ticks;
                    Console.WriteLine(DateTime.Now + ": Start online");
                    logOutEvery = new Random().Next(1000) + 7200;
                }
            }
            else {
                if ((now - startedOnline) / 10000000 > logOutEvery)
                {
                    off = true;
                    startedOffline = DateTime.Now.Ticks;
                    Console.WriteLine(DateTime.Now + ": Start offline");
                    logOutFor = new Random().Next(1000) + 1200;
                    return;
                }
            }

            
            if (backgroundWorkerDoTask.IsBusy || off == true)
            {
                return;
            }
            foreach (TaskCheck taskCheck in config.taskChecks)
            {
                if ((now - taskCheck.lastDone) / 10000000 > taskCheck.checkEvery)
                {
                    Console.WriteLine(Constants.taskNames[taskCheck.taskType]);
                    toolStripStatusLabel1.Text = Constants.taskNames[taskCheck.taskType];
                    backgroundWorkerDoTask.RunWorkerAsync(taskCheck);
                    return;
                }
            }
        }

        private void checkHero()
        {
            try
            {
                HeroInfo heroInfo = adapter.getHeroInfo();
                if (heroInfo.hasUneqItem("Gelding"))
                {
                    adapter.equip("Gelding");
                }
                if (heroInfo.hasUneqItem("Cage"))
                {
                    bool displayed = false;
                    foreach (Note note in notes)
                    {
                        if (note.message.Equals("Cages found"))
                        {
                            displayed = true;
                        }
                    }
                    if (!displayed)
                    {
                        notes.Add(new Note(DateTime.Now.Ticks, "Cages found"));
                        UpdateListViewNote();
                    }
                }
                if (config.heroAdventure && heroInfo.health >= 50 && heroInfo.available)//adventure
                {
                    if (adapter.adventure())
                    {
                        heroInfo.available = false;
                    }
                }
                if (config.heroSolo && heroInfo.health >= config.heroSoloMinHealth && heroInfo.available)//solo oasis
                {
                    foreach (Village village in config.villages)
                    {
                        if (village.id.Equals(config.heroVillageId))
                        {
                            village.zones.Sort(new ZoneComparer());
                            for (int k = 0; k < village.zones.Count; k++)
                            {
                                Console.WriteLine(k);
                                backgroundWorkerDoTask.ReportProgress(k * 100 / village.zones.Count);
                                Zone zone = (Zone)village.zones[k];
                                int def = adapter.getOasisDefend(zone.x, zone.y, false);
                                zone.defend = def;
                                if (def > 0 && def < heroInfo.fighting / config.heroAttackX)
                                {
                                    adapter.getHalfVillageInfo(config.heroVillageId);
                                    String result = adapter.attack(zone.x, zone.y, 1, 0, village.id, true, 0);
                                    zone.status = result;
                                    if (result.StartsWith("Troop sent"))
                                    {
                                        Console.WriteLine("Solo oasis " + zone.getXY());
                                        heroInfo.available = false;
                                        break;
                                    }
                                }

                            }
                        }
                    }
                }
                if (heroInfo.available && heroInfo.health > config.heroClearMinHealth && config.heroClearWithTroop)//clear oasis with troops
                {
                    foreach (Village village in config.villages)
                    {
                        if (village.id.Equals(config.heroVillageId))
                        {
                            VillageInfo villageInfo = adapter.getHalfVillageInfo(village.id);
                            int troopcount = villageInfo.getTroopCount(config.heroTroopType.name);
                            village.zones.Sort(new ZoneComparer());
                            for (int k = 0; k < village.zones.Count; k++)
                            {
                                backgroundWorkerDoTask.ReportProgress(k * 100 / village.zones.Count);
                                Zone zone = (Zone)village.zones[k];
                                int def = adapter.getOasisDefend(zone.x, zone.y, config.heroUseInfantryDef);
                                zone.defend = def;
                                if (def > 0 && def < (troopcount * config.heroTroopType.attack + heroInfo.fighting) / Convert.ToDouble(config.heroTroopAttackX))
                                {
                                    adapter.getHalfVillageInfo(config.heroVillageId);
                                    String result = adapter.attack(zone.x, zone.y, config.heroTroopType.id, troopcount, village.id, true, 0);
                                    if (result.StartsWith("Troop sent"))
                                    {
                                        Console.WriteLine("Clear oasis " + zone.getXY());
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
                if (config.autoAddFighting)
                {
                    adapter.addFighting(heroInfo.pointsToAdd);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
                adapter.login();
            }
        }

        private void normalFarm()
        {
            try
            {
                // for each village
                foreach (Village village in config.villages)
                {
                    // for each type of troop
                    for (int i = 0; i < village.troops.Count; i++)
                    {
                        Troop troop = (Troop)village.troops[i];
                        if (troop.maxPop > 0)
                        {
                            int pop = adapter.getPopulation();
                            if (pop >= troop.maxPop)
                            {
                                Console.WriteLine("Skip this type of troop. Pop too high: " + pop);
                                continue;
                            }
                        }
                        VillageInfo info = adapter.getHalfVillageInfo(village.id);
                        int troopcount = info.getTroopCount(troop.name);
                        if (troopcount == 0)
                        {
                            if (troop.name.Equals("Theutates Thunders"))
                            {
                                troopcount = info.getTroopCount("Theutates Thunder");
                            }
                            else if (troop.name.Equals("Teutonic Knights"))
                            {
                                troopcount = info.getTroopCount("Teutonic Knight");
                            }
                            else if (troop.name.Equals("Haeduans"))
                            {
                                troopcount = info.getTroopCount("Haeduan");
                            }
                        }
                        //farm normal
                        if (troop.number_each_wave >= 1)
                        {
                            int count = 0;
                            while (troopcount >= troop.number_each_wave && count < 100 && info.waves <= troop.xCleanOasis)
                            {
                                Console.WriteLine(troop.name + " " + troopcount);
                                long lastSend = long.MaxValue;
                                int j = 0;
                                for (j = 0; j < village.zones.Count; j++)
                                {
                                    Zone zone1 = (Zone)village.zones[j];
                                    if (zone1.defend == 0)
                                    {
                                        lastSend = zone1.lastSend;
                                        break;
                                    }
                                }
                                long now = DateTime.Now.Ticks;
                                if ((now - lastSend) / 10000000 > 2400)
                                {
                                    village.current = 0;
                                }
                                while (true)
                                {
                                    try
                                    {
                                        if (village.current >= village.zones.Count) village.current = 0;

                                        Zone zone = (Zone)village.zones[village.current];
                                        int def = adapter.getOasisDefend(zone.x, zone.y, false);
                                        zone.defend = def;
                                        String result = "";
                                        if (def == 0)
                                        {
                                            // sending troop in ramdom number
                                            adapter.getHalfVillageInfo(village.id);
                                            result = adapter.attack(zone.x, zone.y, troop.id, troop.number_each_wave, village.id, false, 0);
                                            zone.status = result;
                                        }
                                        else
                                        {
                                            zone.status = "Oasis defend too strong";
                                        }
                                        village.current = (village.current + 1) % village.zones.Count;
                                        if (result.StartsWith("Troop sent"))
                                        {
                                            zone.lastSend = DateTime.Now.Ticks;
                                            break;
                                        }
                                    }
                                    catch (Exception ex)
                                    {
                                        Console.WriteLine(ex.ToString());
                                        adapter.login();
                                    }
                                }
                                info = adapter.getHalfVillageInfo(village.id);
                                troopcount = info.getTroopCount(troop.name);
                                count++;
                                saveConfig();
                                backgroundWorkerDoTask.ReportProgress(count);
                            }
                        }
                    }

                }
            }

            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
                adapter.login();
            }
        }

        private void newGoldClubFarm()
        {
            try
            {
                foreach (FarmList farmlist in config.farmlists)
                {
                    switch (farmlist.farmType)
                    {
                        case 0:
                            VillageInfo info = adapter.getHalfVillageInfo(farmlist.vid.ToString());
                            if (info.waves <= farmlist.maxWaves)
                            {
                                int eid = 1;
                                do
                                {
                                    info = adapter.getHalfVillageInfo(farmlist.vid.ToString());
                                    int troopcount = info.getTroopCount(farmlist.trooptype);
                                    if (troopcount < 2)
                                    {
                                        break;
                                    }
                                    Console.WriteLine(farmlist.trooptype + " " + troopcount);
                                    string result = adapter.getFarmlistTarget(farmlist.vid.ToString(), farmlist.trooptype);
                                    Regex re = new Regex("<form action=\"build.php\\?gid=16&amp;tt=99\" method=\"post\">.+?<input type=\"hidden\" name=\"a\" value=\"(.+?)\" />.+?<input type=\"hidden\" name=\"lid\" value=\"(\\d+)\" />(.+?)</form>");
                                    MatchCollection matches = re.Matches(result);
                                    String form = matches[farmlist.id].Groups[3].Value;
                                    string lid = matches[farmlist.id].Groups[2].Value;
                                    String a = matches[farmlist.id].Groups[1].Value;
                                    //Regex re1 = new Regex("<label for=\"slot(\\d+)\">(.+?)</label>.+?class=\"iReport iReport(\\d+)\"");
                                    Regex reTR = new Regex("<tr class=\"slotRow\">(.+?)</tr>");
                                    MatchCollection matchesTR = reTR.Matches(form);
                                    Regex re1 = new Regex("<label for=\"slot(\\d+)\">(.+?)</label>.+?<span class=\"troopIconAmount\">(\\d+)</span>.+?<td class=\"lastRaid\">(.+?)</td>");
                                    //MatchCollection matches1 = re1.Matches(form);
                                    int raidCount = 0;
                                    int raidselected = 0;

                                    ArrayList entryids = new ArrayList();
                                    ArrayList entryHashKey = new ArrayList();
                                    for (int i = 0; i < matchesTR.Count; i++)
                                    {
                                        String subStr = matchesTR[i].Groups[1].Value;
                                        Console.WriteLine(subStr);
                                        if (subStr.Contains("Own attacking troops"))
                                        {
                                            Console.WriteLine("Attacking already, skipped");
                                            continue;
                                        }
                                        MatchCollection matches1 = re1.Matches(subStr);
                                        if (matches1.Count > 0)
                                        {
                                            string entryId = matches1[0].Groups[1].Value;
                                            string villagename = matches1[0].Groups[2].Value;
                                            int troop = Convert.ToInt32(matches1[0].Groups[3].Value);
                                            string lastraid = matches1[0].Groups[4].Value;
                                            if (raidCount + troop > troopcount)
                                            {
                                                break;
                                            }
                                            backgroundWorkerDoTask.ReportProgress((raidCount + troop) * 100 / troopcount);
                                            Regex re2 = new Regex("(-?\\d+)");
                                            MatchCollection matches2 = re2.Matches(villagename);
                                            if (matches2.Count == 2) //Oasis
                                            {
                                                int x = Convert.ToInt32(matches2[0].Groups[1].Value);
                                                int y = Convert.ToInt32(matches2[1].Groups[1].Value);
                                                if (adapter.getOasisDefend(x, y, true) == 0 && Math.Sqrt((farmlist.avoidX - x) * (farmlist.avoidX - x) + (farmlist.avoidY - y) * (farmlist.avoidY - y)) > farmlist.avoidR)
                                                {
                                                    entryids.Add(entryId);
                                                    raidCount += troop;
                                                    raidselected++;
                                                    Console.WriteLine("selected " + x + "," + y);
                                                }
                                            }
                                            else
                                            {
                                                if (!lastraid.Contains("iReport2") && !lastraid.Contains("iReport3"))
                                                {
                                                    entryids.Add(entryId);
                                                    raidCount += troop;
                                                    raidselected++;
                                                }
                                            }
                                        }
                                    }
                                    Console.WriteLine(raidselected + " raids selected");
                                    if (raidselected > 0)
                                    {
                                        eid = adapter.activateFarmlist(lid, a, entryids);
                                    }
                                    if (eid == -2)//banned temporarily
                                    {
                                        adapter.logout();
                                        bool loggin = false;
                                        do
                                        {
                                            loggin = (adapter.login() != null);
                                        } while (loggin == false);
                                    }
                                    if (eid == 0)//perfect
                                    {
                                        foreach (string hashKey in entryHashKey)
                                        {
                                            raidLog.Remove(hashKey);
                                            raidLog.Add(hashKey, DateTime.Now.Ticks);
                                        }
                                    }
                                } while (eid < 0);
                            }
                            break;
                        case 1:
                            if (farmlist.maxPopulation > 0)
                            {
                                int pop = adapter.getPopulation();
                                if (pop >= farmlist.maxPopulation)
                                {
                                    Console.WriteLine("Skip this list. Pop too high: " + pop);
                                    continue;
                                }
                            }
                            info = adapter.getHalfVillageInfo(farmlist.vid.ToString());
                            if (info.waves <= farmlist.maxWaves)
                            {
                                int eid = 1;
                                do
                                {
                                    info = adapter.getHalfVillageInfo(farmlist.vid.ToString());
                                    int troopcount = info.getTroopCount(farmlist.trooptype);
                                    if (troopcount < 2)
                                    {
                                        break;
                                    }
                                    Console.WriteLine(farmlist.trooptype + " " + troopcount);
                                    string result = adapter.getFarmlistTarget(farmlist.vid.ToString(), farmlist.trooptype);
                                    Regex re = new Regex("<form action=\"build.php\\?gid=16&amp;tt=99\" method=\"post\">.+?<input type=\"hidden\" name=\"a\" value=\"(.+?)\" />.+?<input type=\"hidden\" name=\"lid\" value=\"(\\d+)\" />(.+?)</form>");
                                    MatchCollection matches = re.Matches(result);
                                    String form = matches[farmlist.id].Groups[3].Value;
                                    string lid = matches[farmlist.id].Groups[2].Value;
                                    String a = matches[farmlist.id].Groups[1].Value;
                                    //Regex re1 = new Regex("<label for=\"slot(\\d+)\">(.+?)</label>.+?class=\"iReport iReport(\\d+)\"");
                                    Regex re1 = new Regex("<label for=\"slot(\\d+)\">(.+?)</label>.+?<span class=\"troopIconAmount\">(\\d+)</span>.+?<td class=\"lastRaid\">(.+?)</td>");
                                    MatchCollection matches1 = re1.Matches(form);
                                    int raidCount = 0;
                                    int raidselected = 0;

                                    ArrayList entryids = new ArrayList();
                                    ArrayList entryHashKey = new ArrayList();
                                    for (int i = 0; i < matches1.Count; i++)
                                    {
                                        string entryId = matches1[i].Groups[1].Value;
                                        string villagename = matches1[i].Groups[2].Value;
                                        int troop = Convert.ToInt32(matches1[i].Groups[3].Value);
                                        string lastraid = matches1[i].Groups[4].Value;
                                        if (raidCount + troop > troopcount)
                                        {
                                            break;
                                        }
                                        backgroundWorkerDoTask.ReportProgress((raidCount + troop) * 100 / troopcount);
                                        Regex re2 = new Regex("(-?\\d+)");
                                        MatchCollection matches2 = re2.Matches(villagename);
                                        if (matches2.Count == 2) //Oasis
                                        {
                                            int x = Convert.ToInt32(matches2[0].Groups[1].Value);
                                            int y = Convert.ToInt32(matches2[1].Groups[1].Value);
                                            long lastRaid = 0;
                                            string hashKey = Util.getHashKey(x, y);
                                            if (raidLog.ContainsKey(hashKey))
                                            {
                                                lastRaid = (long)raidLog[hashKey];
                                            }
                                            if (((DateTime.Now.Ticks - lastRaid) / 10000000) > config.raidInterval)
                                            {
                                                if (adapter.getOasisDefend(x, y, true) == 0 && Math.Sqrt((farmlist.avoidX - x) * (farmlist.avoidX - x) + (farmlist.avoidY - y) * (farmlist.avoidY - y)) > farmlist.avoidR)
                                                {
                                                    entryids.Add(entryId);
                                                    entryHashKey.Add(hashKey);
                                                    raidCount += troop;
                                                    raidselected++;
                                                    Console.WriteLine("selected " + x + "," + y);
                                                }
                                            }
                                        }
                                        else
                                        {
                                            long lastRaid = 0;
                                            string hashKey = villagename;
                                            if (raidLog.ContainsKey(hashKey))
                                            {
                                                lastRaid = (long)raidLog[hashKey];
                                            }
                                            if (((DateTime.Now.Ticks - lastRaid) / 10000000) > config.raidInterval)
                                            {
                                                if (!lastraid.Contains("iReport2") && !lastraid.Contains("iReport3"))
                                                {
                                                    entryids.Add(entryId);
                                                    entryHashKey.Add(hashKey);
                                                    raidCount += troop;
                                                    raidselected++;
                                                }
                                            }
                                        }
                                    }
                                    Console.WriteLine(raidselected + " raids selected");
                                    if (raidselected > 0)
                                    {
                                        eid = adapter.activateFarmlist(lid, a, entryids);
                                    }
                                    else
                                    {
                                        eid = 0;
                                    }
                                    if (eid == -2)//banned temporarily
                                    {
                                        adapter.logout();
                                        bool loggin = false;
                                        do
                                        {
                                            loggin = (adapter.login() != null);
                                        } while (loggin == false);
                                    }
                                    if (eid == 0)//perfect
                                    {
                                        foreach (string hashKey in entryHashKey)
                                        {
                                            raidLog.Remove(hashKey);
                                            raidLog.Add(hashKey, DateTime.Now.Ticks);
                                        }
                                    }
                                } while (eid < 0);
                            }
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                adapter.login();
            }
        }

        private void checkBuilding()
        {
            try
            {
                for (int i = 0; i < config.villages.Count; i++)
                {
                    backgroundWorkerDoTask.ReportProgress(i * 100 / config.villages.Count);
                    Village village = (Village)config.villages[i];
                    if (village.buildingQueues.Count == 0 && !village.autoUpRes)
                    {
                        continue;
                    }
                    villages[i].detailedInfo = adapter.getHalfVillageInfo(village.id);
                    if (villages[i].detailedInfo.buildBusy(checkBoxPlus.Checked))
                    {
                        continue;
                    }
                    villages[i].detailedInfo = adapter.getVillageInfo(village.id);
                    if (villages[i].detailedInfo.freeCop <= 4 && !villages[i].detailedInfo.buildBusy(checkBoxPlus.Checked))
                    {
                        Building cropToBuild = villages[i].detailedInfo.getLowestCropland();
                        if (adapter.build(cropToBuild.buildLink, 0))
                        {
                            Console.WriteLine("No free crop. Built crop");
                        }
                        else
                        {
                            Console.WriteLine("No free crop. But cannot build crop");
                        }
                        continue;
                    }
                    if (Constants.tribe == 0)
                    {
                        if (!villages[i].detailedInfo.buildBusy(checkBoxPlus.Checked))
                        {
                            Building building = village.getFirstResField();
                            if (building != null)
                            {
                                if (adapter.build(building.buildLink, 0))
                                {
                                    Console.WriteLine("Built " + building.name + " level " + building.level);
                                }
                            }
                            else if (village.autoUpRes)
                            {
                                ArrayList lowestFields = new ArrayList();
                                lowestFields.Add(villages[i].detailedInfo.getLowestClayPit());
                                lowestFields.Add(villages[i].detailedInfo.getLowestWoodcutter());
                                lowestFields.Add(villages[i].detailedInfo.getLowestIronMine());
                                lowestFields.Add(villages[i].detailedInfo.getLowestCropland());
                                lowestFields.Sort(new BuildingComparer());
                                foreach (Building toBuild in lowestFields)
                                {
                                    if (adapter.build(toBuild.buildLink, 0))
                                    {
                                        Console.WriteLine("Built " + toBuild.name + " level " + toBuild.level);
                                        break;
                                    }
                                }
                            }
                        }
                        villages[i].detailedInfo = adapter.getVillageInfo(village.id);
                        if (!villages[i].detailedInfo.buildBusy(checkBoxPlus.Checked))
                        {
                            Building building = village.getFirstBuilding();
                            if (building != null)
                            {
                                if (building.buildLink.StartsWith("build"))
                                {
                                    if (adapter.build(building.buildLink, 0))
                                    {
                                        Console.WriteLine("Built " + building.name + " level " + building.level);
                                    }
                                }
                                else if (villages[i].detailedInfo.emptySlots.Count > 0)
                                {
                                    Building emptySlot = (Building)villages[i].detailedInfo.emptySlots[0];
                                    if (adapter.build(emptySlot.buildLink, Convert.ToInt32(building.buildLink)))
                                    {
                                        Console.WriteLine("Built " + building.name + " level " + building.level);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        Building buildingToBuild = village.getFirstAny();
                        if (buildingToBuild != null)
                        {
                            if (buildingToBuild.resField)
                            {
                                if (adapter.build(buildingToBuild.buildLink, 0))
                                {
                                    Console.WriteLine("Built " + buildingToBuild.name + " level " + buildingToBuild.level);
                                }
                            }
                            else
                            {
                                if (buildingToBuild.buildLink.StartsWith("build"))
                                {
                                    if (adapter.build(buildingToBuild.buildLink, 0))
                                    {
                                        Console.WriteLine("Built " + buildingToBuild.name + " level " + buildingToBuild.level);
                                    }
                                }
                                else if (villages[i].detailedInfo.emptySlots.Count > 0)
                                {
                                    Building emptySlot = (Building)villages[i].detailedInfo.emptySlots[0];
                                    if (adapter.build(emptySlot.buildLink, Convert.ToInt32(buildingToBuild.buildLink)))
                                    {
                                        Console.WriteLine("Built " + buildingToBuild.name + " level " + buildingToBuild.level);
                                    }
                                }
                            }
                        }
                        else if (village.autoUpRes)
                        {
                            ArrayList lowestFields = new ArrayList();
                            lowestFields.Add(villages[i].detailedInfo.getLowestClayPit());
                            lowestFields.Add(villages[i].detailedInfo.getLowestWoodcutter());
                            lowestFields.Add(villages[i].detailedInfo.getLowestIronMine());
                            lowestFields.Add(villages[i].detailedInfo.getLowestCropland());
                            lowestFields.Sort(new BuildingComparer());
                            foreach (Building toBuild in lowestFields)
                            {
                                if (adapter.build(toBuild.buildLink, 0))
                                {
                                    Console.WriteLine("Built " + toBuild.name + " level " + toBuild.level);
                                    break;
                                }
                            }
                        }
                    }
                    villages[i].detailedInfo = adapter.getVillageInfo(village.id);
                    ArrayList buildings = new ArrayList();
                    foreach (Building building in villages[i].detailedInfo.buildings)
                    {
                        buildings.Add(building);
                    }
                    foreach (Building building in villages[i].detailedInfo.resFields)
                    {
                        buildings.Add(building);
                    }

                    for (int j = village.buildingQueues.Count - 1; j >= 0; j--)
                    {
                        Building queueBuilding = (Building)village.buildingQueues[j];
                        foreach (Building building in buildings)
                        {
                            if (!queueBuilding.buildLink.StartsWith("build") && (!queueBuilding.resField) && queueBuilding.name.Contains(building.name))
                            {
                                queueBuilding.buildLink = building.buildLink;
                            }
                            if (queueBuilding.buildLink.Equals(building.buildLink) && queueBuilding.level <= building.level)
                            {
                                village.buildingQueues.Remove(queueBuilding);
                            }
                        }
                    }
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
                adapter.login();
            }
        }

        private void checkMarkets()
        {
            try
            {
                int count = 0;
                foreach (Route route in config.routes)
                {
                    int lumber = 0;
                    int clay = 0;
                    int iron = 0;
                    int crop = 0;
                    VillageInfo sourceVillageInfo = adapter.getHalfVillageInfo(route.fromId);
                    if (!route.toId.Equals(""))
                    {
                        VillageInfo destVillageInfo = adapter.getHalfVillageInfo(route.toId);
                        if (route.fromObject)
                        {
                            if (route.unitInPercentage)
                            {
                                //source > x%
                                if (route.lumber && sourceVillageInfo.lumber > route.value * sourceVillageInfo.maxStore / 100)
                                {
                                    lumber = Math.Min(sourceVillageInfo.lumber - route.value * sourceVillageInfo.maxStore / 100, destVillageInfo.maxStore - destVillageInfo.lumber);
                                }
                                if (route.clay && sourceVillageInfo.clay > route.value * sourceVillageInfo.maxStore / 100)
                                {
                                    clay = Math.Min(sourceVillageInfo.clay - route.value * sourceVillageInfo.maxStore / 100, destVillageInfo.maxStore - destVillageInfo.clay);
                                }
                                if (route.iron && sourceVillageInfo.iron > route.value * sourceVillageInfo.maxStore / 100)
                                {
                                    iron = Math.Min(sourceVillageInfo.iron - route.value * sourceVillageInfo.maxStore / 100, destVillageInfo.maxStore - destVillageInfo.iron);
                                }
                                if (route.crop && sourceVillageInfo.crop > route.value * sourceVillageInfo.maxCrop / 100)
                                {
                                    crop = Math.Min(sourceVillageInfo.crop - route.value * sourceVillageInfo.maxCrop / 100, destVillageInfo.maxCrop - destVillageInfo.crop);
                                }
                            }
                            else
                            {
                                //source > x
                                if (route.lumber && sourceVillageInfo.lumber > route.value)
                                {
                                    lumber = Math.Min(sourceVillageInfo.lumber - route.value, destVillageInfo.maxStore - destVillageInfo.lumber);
                                }
                                if (route.clay && sourceVillageInfo.clay > route.value)
                                {
                                    clay = Math.Min(sourceVillageInfo.clay - route.value, destVillageInfo.maxStore - destVillageInfo.clay);
                                }
                                if (route.iron && sourceVillageInfo.iron > route.value)
                                {
                                    iron = Math.Min(sourceVillageInfo.iron - route.value, destVillageInfo.maxStore - destVillageInfo.iron);
                                }
                                if (route.crop && sourceVillageInfo.crop > route.value)
                                {
                                    crop = Math.Min(sourceVillageInfo.crop - route.value, destVillageInfo.maxCrop - destVillageInfo.crop);
                                }
                            }

                        }
                        else
                        {
                            if (route.unitInPercentage)
                            {
                                //destination < x%
                                if (route.lumber && destVillageInfo.lumber < route.value * destVillageInfo.maxStore / 100)
                                {
                                    lumber = Math.Min(route.value * destVillageInfo.maxStore / 100 - destVillageInfo.lumber, sourceVillageInfo.lumber);
                                }
                                if (route.clay && destVillageInfo.clay < route.value * destVillageInfo.maxStore / 100)
                                {
                                    clay = Math.Min(route.value * destVillageInfo.maxStore / 100 - destVillageInfo.clay, sourceVillageInfo.clay);
                                }
                                if (route.iron && destVillageInfo.iron < route.value * destVillageInfo.maxStore / 100)
                                {
                                    iron = Math.Min(route.value * destVillageInfo.maxStore / 100 - destVillageInfo.iron, sourceVillageInfo.iron);
                                }
                                if (route.crop && destVillageInfo.crop < route.value * destVillageInfo.maxCrop / 100)
                                {
                                    crop = Math.Min(route.value * destVillageInfo.maxCrop / 100 - destVillageInfo.crop, sourceVillageInfo.crop);
                                }
                            }
                            else
                            {
                                //destination < x
                                if (route.lumber && destVillageInfo.lumber < route.value)
                                {
                                    lumber = Math.Min(route.value - destVillageInfo.lumber, sourceVillageInfo.lumber);
                                }
                                if (route.clay && destVillageInfo.clay < route.value)
                                {
                                    clay = Math.Min(route.value - destVillageInfo.clay, sourceVillageInfo.clay);
                                }
                                if (route.iron && destVillageInfo.iron < route.value)
                                {
                                    iron = Math.Min(route.value - destVillageInfo.iron, sourceVillageInfo.iron);
                                }
                                if (route.crop && destVillageInfo.crop < route.value)
                                {
                                    crop = Math.Min(route.value - destVillageInfo.crop, sourceVillageInfo.crop);
                                }
                            }
                        }
                    }
                    else
                    {
                        if (route.fromObject)
                        {
                            if (route.unitInPercentage)
                            {
                                //source > x%
                                if (route.lumber && sourceVillageInfo.lumber > route.value * sourceVillageInfo.maxStore / 100)
                                {
                                    lumber = sourceVillageInfo.lumber - route.value * sourceVillageInfo.maxStore / 100;
                                }
                                if (route.clay && sourceVillageInfo.clay > route.value * sourceVillageInfo.maxStore / 100)
                                {
                                    clay = sourceVillageInfo.clay - route.value * sourceVillageInfo.maxStore / 100;
                                }
                                if (route.iron && sourceVillageInfo.iron > route.value * sourceVillageInfo.maxStore / 100)
                                {
                                    iron = sourceVillageInfo.iron - route.value * sourceVillageInfo.maxStore / 100;
                                }
                                if (route.crop && sourceVillageInfo.crop > route.value * sourceVillageInfo.maxCrop / 100)
                                {
                                    crop = sourceVillageInfo.crop - route.value * sourceVillageInfo.maxCrop / 100;
                                }
                            }
                            else
                            {
                                //source > x
                                if (route.lumber && sourceVillageInfo.lumber > route.value)
                                {
                                    lumber = sourceVillageInfo.lumber - route.value;
                                }
                                if (route.clay && sourceVillageInfo.clay > route.value)
                                {
                                    clay = sourceVillageInfo.clay - route.value;
                                }
                                if (route.iron && sourceVillageInfo.iron > route.value)
                                {
                                    iron = sourceVillageInfo.iron - route.value;
                                }
                                if (route.crop && sourceVillageInfo.crop > route.value)
                                {
                                    crop = sourceVillageInfo.crop - route.value;
                                }
                            }

                        }
                    }

                    if (lumber != 0 || clay != 0 || iron != 0 || crop != 0)
                    {
                        if (!config.fullMerchan || (lumber + clay + iron + crop) >= config.merchanCapacity)
                        {
                            adapter.sendRes(route.fromId, route.toName, lumber, clay, iron, crop);
                        }
                    }
                    count++;
                    backgroundWorkerDoTask.ReportProgress(count * 100 / config.routes.Count);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
                adapter.login();
            }
        }

        private void buyTroops()
        {
            try
            {
                for (int i = 0; i < config.villages.Count; i++)
                {
                    backgroundWorkerDoTask.ReportProgress(i * 100 / config.villages.Count);
                    Village village = (Village)config.villages[i];
                    foreach (BuyTroop buyTroop in village.troopToBuy)
                    {
                        if (!buyTroop.item.Equals(""))
                        {
                            adapter.equip(buyTroop.item);
                        }
                        adapter.buyTroop(village.id, buyTroop.buildingGID, buyTroop.troopID, int.MaxValue, buyTroop.maxQueueTime);
                    }
                }
            }
            catch (Exception ex)
            {
                Console.Write(ex.StackTrace);
                adapter.login();
            }
        }

        private void checkRaidScore()
        {
            try
            {
                int raidScore = adapter.getRaidStatistics();
                string fileName = Util.getRaidFileName(config);
                Console.WriteLine(fileName);
                using (StreamWriter w = File.AppendText(fileName))
                {
                    w.WriteLine(raidScore+","+DateTime.Now.Ticks);
                    w.Flush();
                    w.Close();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
                adapter.login();
            }
        }

        private void checkScouts()
        {
            try
            {
                foreach (Village village in config.villages)
                {
                    if (village.scoutTargets.Count > 0)
                    {
                        VillageInfo info = adapter.getHalfVillageInfo(village.id);
                        string troopName = Constants.scoutName[Constants.tribe];
                        int troopId = Constants.scoutId[Constants.tribe];
                        int troopcount = info.getTroopCount(troopName);
                        for (int i = 0; i < Math.Min(village.scoutTargets.Count, troopcount); i++)
                        {
                            backgroundWorkerDoTask.ReportProgress(i * 100 / village.scoutTargets.Count);
                            Zone zone = (Zone)village.scoutTargets[village.currentScout];
                            if (adapter.scoutable(zone.x, zone.y))
                            {
                                adapter.getHalfVillageInfo(village.id);
                                string result = adapter.attack(zone.x, zone.y, troopId, 1, village.id, false, 1);
                                zone.status = result;
                                zone.lastSend = DateTime.Now.Ticks;
                            }
                            village.currentScout++;
                        }
                    }
                }
                saveConfig();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
                adapter.login();
            }
        }

        private void checkParty()
        {
            try
            {
                for (int i = 0; i < config.villages.Count; i++)
                {
                    backgroundWorkerDoTask.ReportProgress(i * 100 / config.villages.Count);
                    Village village = (Village)config.villages[i];
                    if (village.autoParty)
                    {
                        adapter.party(village.id);
                    }
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
                adapter.login();
            }
        }

        private void AutoTask()
        {
            try
            {
                Task task = adapter.checkTask();
                if (task.number >= 5||task.number ==0)
                {
                    HeroInfo hero = adapter.getHeroInfo();
                    if (hero.available && hero.health > 50)
                    {
                        adapter.adventure();
                    }
                    adapter.addFighting(hero.pointsToAdd);
                }
                if (task.completed)
                {
                    adapter.completeQuest(task.number);
                    Console.WriteLine("completed quest " + task.number);
                    AutoTask();
                }
                else
                {
                    VillageInfo village = adapter.getVillageInfo("0");
                    if (village.freeCop <= 0 && !village.buildBusy(checkBoxPlus.Checked))
                    {
                        Building cropToBuild = village.getLowestCropland();
                        if (adapter.build(cropToBuild.buildLink, 0))
                        {
                            Console.WriteLine("No free crop. Built crop");
                        }
                        else
                        {
                            Console.WriteLine("No free crop. But cannot build crop");
                        }
                    }
                    switch (task.number)
                    {
                        case 0:
                            if (village.taskComplete > 0)
                            {
                                adapter.completeLaterQuest(village.taskComplete);
                                AutoTask();
                            }
                            else
                            {
                                //bat dau buid queue
                                //main building -> 5
                                if (village.getLevelByName("Main Building") < 5 && !village.buildBusy(checkBoxPlus.Checked))
                                {
                                    if (adapter.build("build.php?gid=15", 0))
                                    {
                                        Console.WriteLine("Upgrade main building");
                                    }
                                    else
                                    {
                                        Console.WriteLine("Could not upgrade main building");
                                    }
                                    break;
                                }

                                //embassy
                                Building emptySlot = (Building)village.emptySlots[0];
                                if (adapter.build(emptySlot.buildLink, 18))
                                {
                                    Console.WriteLine("Built embassy level 1");
                                }
                                else
                                {
                                    Console.WriteLine("Cannot build embassy 1");
                                }

                                // res fields -> 5
                                ArrayList lowestFields = new ArrayList();
                                lowestFields.Add(village.getLowestClayPit());
                                lowestFields.Add(village.getLowestWoodcutter());
                                lowestFields.Add(village.getLowestIronMine());
                                lowestFields.Add(village.getLowestCropland());
                                lowestFields.Sort(new BuildingComparer());
                                Building tmp = (Building)lowestFields[0];
                                if (tmp.level < 4)
                                {
                                    foreach (Building toBuild in lowestFields)
                                    {
                                        if (adapter.build(toBuild.buildLink, 0))
                                        {
                                            Console.WriteLine("Built " + toBuild.name + " level " + toBuild.level);
                                            break;
                                        }
                                    }
                                }
                                else
                                {

                                    //warehouse -> 7, granary -> 6
                                    if (village.getLevelByName("Warehouse") < 7 && !village.buildBusy(checkBoxPlus.Checked))
                                    {
                                        if (adapter.build("build.php?gid=10", 0))
                                        {
                                            Console.WriteLine("Upgrade warehouse");
                                        }
                                        else
                                        {
                                            Console.WriteLine("Could not upgrade warehouse");
                                        }
                                    }

                                    if (village.getLevelByName("Warehouse") >= 7 && village.getLevelByName("Granary") < 6 && !village.buildBusy(checkBoxPlus.Checked))
                                    {
                                        if (adapter.build("build.php?gid=11", 0))
                                        {
                                            Console.WriteLine("Upgrade granary");
                                        }
                                        else
                                        {
                                            Console.WriteLine("Could not upgrade granary");
                                        }
                                    }

                                    //build cp buildings
                                    //main building -> 10
                                    if (village.getLevelByName("Granary") >= 6&&village.getLevelByName("Main Building") < 10 && !village.buildBusy(checkBoxPlus.Checked))
                                    {
                                        if (adapter.build("build.php?gid=15", 0))
                                        {
                                            Console.WriteLine("Upgrade main building");
                                        }
                                        else
                                        {
                                            Console.WriteLine("Could not upgrade main building");
                                        }
                                    }
                                    //market -> 8
                                    if (village.getLevelByName("Main Building")>=10&&village.getLevelByName("Marketplace") < 8 && !village.buildBusy(checkBoxPlus.Checked))
                                    {
                                        if (adapter.build("build.php?gid=17", 0))
                                        {
                                            Console.WriteLine("Upgrade market");
                                        }
                                        else
                                        {
                                            Console.WriteLine("Could not upgrade market");
                                        }
                                    }

                                    //embassy -> 6
                                    if (village.getLevelByName("Marketplace") >= 8 && village.getLevelByName("Embassy") < 6 && !village.buildBusy(checkBoxPlus.Checked))
                                    {
                                        if (adapter.build("build.php?gid=18", 0))
                                        {
                                            Console.WriteLine("Upgrade embassy");
                                        }
                                        else
                                        {
                                            Console.WriteLine("Could not upgrade embassy");
                                        }
                                    }
                                    //residence -> 10
                                    if (village.getLevelByName("Embassy") >= 6)
                                    {
                                        emptySlot = (Building)village.emptySlots[0];
                                        if (adapter.build(emptySlot.buildLink, 25))
                                        {
                                            Console.WriteLine("Built embassy level 1");
                                        }
                                        else
                                        {
                                            Console.WriteLine("Cannot build embassy 1");
                                        }
                                        if (village.getLevelByName("Residence") < 10 && !village.buildBusy(checkBoxPlus.Checked))
                                        {
                                            if (adapter.build("build.php?gid=25", 0))
                                            {
                                                Console.WriteLine("Upgrade residence");
                                            }
                                            else
                                            {
                                                Console.WriteLine("Could not upgrade residence");
                                            }
                                        }
                                    }
                                }
                            }
                            break;
                        case 1:
                            VillageInfo villageInfo = adapter.getVillageInfo("0");
                            if (!villageInfo.buildBusy(checkBoxPlus.Checked))
                            {
                                if (adapter.build("build.php?id=1", 0))
                                {
                                    Console.WriteLine("Built wood lvl 1");
                                    AutoTask();
                                }
                                else
                                {
                                    Console.WriteLine("cannot build wood lvl 1");
                                }
                            }
                            break;
                        case 2:
                            villageInfo = adapter.getVillageInfo("0");
                            if (!villageInfo.buildBusy(checkBoxPlus.Checked))
                            {
                                if (adapter.build("build.php?id=2", 0))
                                {
                                    Console.WriteLine("Built crop lvl 1");
                                    AutoTask();
                                }
                                else
                                {
                                    Console.WriteLine("cannot build crop lvl 1");
                                }
                            }
                            break;
                        case 3:
                            adapter.setDoveOfPeace();
                            AutoTask();
                            break;
                        case 4:
                            villageInfo = adapter.getVillageInfo("0");
                            if (!villageInfo.buildBusy(checkBoxPlus.Checked))
                            {
                                if (adapter.build("build.php?id=39", 16))
                                {
                                    Console.WriteLine("Built rally lvl 1");
                                    AutoTask();
                                }
                                else
                                {
                                    Console.WriteLine("cannot build rally lvl 1");
                                }
                            }
                            break;
                        case 5:
                            HeroInfo hero = adapter.getHeroInfo();
                            if (hero.available && hero.health > 50)
                            {
                                adapter.adventure();
                                Console.WriteLine("went to adventure");
                                AutoTask();
                            }
                            break;
                        case 6:
                            int rank = adapter.getRank();
                            adapter.postRankInfo(rank);
                            AutoTask();
                            break;
                        case 7:
                            villageInfo = adapter.getVillageInfo("0");
                            if (!villageInfo.buildBusy(checkBoxPlus.Checked) && villageInfo.getLevel("build.php?id=4") == 0)
                            {
                                if (!villageInfo.buildBusy(checkBoxPlus.Checked))
                                {
                                    if (adapter.build("build.php?id=4", 0))
                                    {
                                        Console.WriteLine("Built iron lvl 1");
                                        return;
                                    }
                                    else
                                    {
                                        Console.WriteLine("cannot build iron lvl 1");
                                    }
                                }
                            }
                            if (!villageInfo.buildBusy(checkBoxPlus.Checked) && villageInfo.getLevel("build.php?id=4") != 0 && villageInfo.getLevel("build.php?id=5") == 0)
                            {
                                if (!villageInfo.buildBusy(checkBoxPlus.Checked))
                                {
                                    if (adapter.build("build.php?id=5", 0))
                                    {
                                        Console.WriteLine("Built clay lvl 1");
                                        AutoTask();
                                    }
                                    else
                                    {
                                        Console.WriteLine("cannot build clay lvl 1");
                                    }
                                }
                            }
                            break;

                        case 8:
                            if (adapter.readTaskMessage())
                            {
                                Console.WriteLine("Read task message");
                                AutoTask();
                            }
                            break;
                        case 9:
                            villageInfo = adapter.getVillageInfo("0");
                            if (!villageInfo.buildBusy(checkBoxPlus.Checked) && villageInfo.getLevel("build.php?id=6") == 0)
                            {
                                if (adapter.build("build.php?id=6", 0))
                                {
                                    Console.WriteLine("Built clay lvl 1");
                                }
                                else
                                {
                                    Console.WriteLine("cannot build clay lvl 1");
                                }
                                return;
                            }
                            if (!villageInfo.buildBusy(checkBoxPlus.Checked) && villageInfo.getLevel("build.php?id=3") == 0)
                            {
                                if (adapter.build("build.php?id=3", 0))
                                {
                                    Console.WriteLine("Built wood lvl 1");
                                }
                                else
                                {
                                    Console.WriteLine("cannot build wood lvl 1");
                                }
                                return;
                            }
                            if (!villageInfo.buildBusy(checkBoxPlus.Checked) && villageInfo.getLevel("build.php?id=8") == 0)
                            {
                                if (adapter.build("build.php?id=8", 0))
                                {
                                    Console.WriteLine("Built crop lvl 1");
                                }
                                else
                                {
                                    Console.WriteLine("cannot build crop lvl 1");
                                }
                                return;
                            }
                            if (!villageInfo.buildBusy(checkBoxPlus.Checked) && villageInfo.getLevel("build.php?id=7") == 0)
                            {
                                if (adapter.build("build.php?id=7", 0))
                                {
                                    Console.WriteLine("Built iron lvl 1");
                                }
                                else
                                {
                                    Console.WriteLine("cannot build iron lvl 1");
                                }
                                return;
                            }
                            break;
                        case 10:
                            village = adapter.getHalfVillageInfo("0");
                            String mapInfo = adapter.postRequestMapInfo(village.x.ToString(), village.y.ToString());
                            Regex re = new Regex("{\"x\":\"(-?\\d+)\",\"y\":\"(-?\\d+)\",\"u\":\"(\\d+)\",\"d\":\"(\\d+)\",\"c\":\"{k.dt} " + task.info + "\"");
                            MatchCollection matches = re.Matches(mapInfo);
                            if (matches.Count > 0)
                            {
                                adapter.postNeiborInfo(matches[0].Groups[1].Value, matches[0].Groups[2].Value);
                                AutoTask();
                            }
                            break;
                        case 11:
                            break;
                        case 12:
                            adapter.readAllMiscReport();
                            AutoTask();
                            break;
                        case 13:
                            break;
                        case 14:
                            village = adapter.getVillageInfo("0");
                            ArrayList lowestFields1 = new ArrayList();
                            lowestFields1.Add(village.getLowestClayPit());
                            lowestFields1.Add(village.getLowestWoodcutter());
                            lowestFields1.Add(village.getLowestIronMine());
                            lowestFields1.Add(village.getLowestCropland());
                            lowestFields1.Sort(new BuildingComparer());
                            Building tmp1 = (Building)lowestFields1[0];
                            if (tmp1.level >= 1)
                            {
                                AutoTask();
                            }
                            else
                            {
                                foreach (Building toBuild in lowestFields1)
                                {
                                    if (adapter.build(toBuild.buildLink, 0))
                                    {
                                        Console.WriteLine("Built " + toBuild.name + " level " + toBuild.level);
                                        break;
                                    }
                                }
                            }
                            break;
                        case 15:
                            adapter.setDoveOfPeace();
                            AutoTask();
                            break;
                        case 16:
                            village = adapter.getVillageInfo("0");
                            if (village.emptySlots.Count > 0 && !village.buildBusy(checkBoxPlus.Checked))
                            {
                                Building emptySlot = (Building)village.emptySlots[0];
                                if (adapter.build(emptySlot.buildLink, 23))
                                {
                                    Console.WriteLine("Built cranny level 1");
                                    AutoTask();
                                }
                                else
                                {
                                    Console.WriteLine("Cannot build cranny level 1");
                                }
                            }
                            break;
                        case 17:
                            villageInfo = adapter.getVillageInfo("0");
                            if (!villageInfo.buildBusy(checkBoxPlus.Checked) && villageInfo.getLevel("build.php?id=6") == 1)
                            {
                                if (adapter.build("build.php?id=6", 0))
                                {
                                    Console.WriteLine("Built clay lvl 2");
                                }
                                else
                                {
                                    Console.WriteLine("cannot build clay lvl 2");
                                }
                                return;
                            }
                            if (!villageInfo.buildBusy(checkBoxPlus.Checked) && villageInfo.getLevel("build.php?id=3") == 1)
                            {
                                if (adapter.build("build.php?id=3", 0))
                                {
                                    Console.WriteLine("Built wood lvl 2");
                                }
                                else
                                {
                                    Console.WriteLine("cannot build wood lvl 2");
                                }
                                return;
                            }
                            if (!villageInfo.buildBusy(checkBoxPlus.Checked) && villageInfo.getLevel("build.php?id=8") == 1)
                            {
                                if (adapter.build("build.php?id=8", 0))
                                {
                                    Console.WriteLine("Built crop lvl 2");
                                }
                                else
                                {
                                    Console.WriteLine("cannot build crop lvl 2");
                                }
                                return;
                            }
                            if (!villageInfo.buildBusy(checkBoxPlus.Checked) && villageInfo.getLevel("build.php?id=7") == 1)
                            {
                                if (adapter.build("build.php?id=7", 0))
                                {
                                    Console.WriteLine("Built iron lvl 2");
                                }
                                else
                                {
                                    Console.WriteLine("cannot build iron lvl 2");
                                }
                                return;
                            }
                            break;
                        case 18:
                            adapter.postBarrackCost();
                            AutoTask();
                            break;
                        case 19:
                            village = adapter.getVillageInfo("0");
                            if (village.getLevel("build.php?id=26") < 3 && !village.buildBusy(checkBoxPlus.Checked))
                            {
                                if (adapter.build("build.php?id=26", 0))
                                {
                                    Console.WriteLine("Upgrade main building");
                                }
                                else
                                {
                                    Console.WriteLine("Could not upgrade main building");
                                }
                            }
                            break;
                        case 20:
                            rank = adapter.getRank();
                            adapter.postRankInfo(rank);
                            AutoTask();
                            break;
                        case 21:
                            if (task.info.Equals("Construct a granary"))
                            {
                                village = adapter.getVillageInfo("0");
                                if (village.emptySlots.Count > 0 && !village.buildBusy(checkBoxPlus.Checked))
                                {
                                    Building emptySlot = (Building)village.emptySlots[0];
                                    if (adapter.build(emptySlot.buildLink, 11))
                                    {
                                        Console.WriteLine("Built granary level 1");
                                    }
                                    else
                                    {
                                        Console.WriteLine("Cannot build granary level 1");
                                    }
                                }
                                break;
                            }
                            else
                            {
                                adapter.choseEconomy();
                            }
                            break;
                        case 22:
                            village = adapter.getVillageInfo("0");
                            if (village.emptySlots.Count > 0 && !village.buildBusy(checkBoxPlus.Checked))
                            {
                                Building emptySlot = (Building)village.emptySlots[0];
                                if (adapter.build(emptySlot.buildLink, 10))
                                {
                                    Console.WriteLine("Built warehouse level 1");
                                }
                                else
                                {
                                    Console.WriteLine("Cannot build warehouse level 1");
                                }
                            }
                            break;
                        case 23:
                            village = adapter.getVillageInfo("0");

                            if (village.getLevel("build.php?id=21") < 3 && !village.buildBusy(checkBoxPlus.Checked))
                            {
                                if (adapter.build("build.php?id=21", 0))
                                {
                                    Console.WriteLine("Upgrade warehouse");
                                }
                                else
                                {
                                    Console.WriteLine("Could not upgrade warehouse");
                                }
                            }

                            if (village.getLevel("build.php?id=20") < 3 && !village.buildBusy(checkBoxPlus.Checked))
                            {
                                if (adapter.build("build.php?id=20", 0))
                                {
                                    Console.WriteLine("Upgrade granary");
                                }
                                else
                                {
                                    Console.WriteLine("Could not upgrade granary");
                                }
                                break;
                            }

                            if (village.getLevel("build.php?id=20") >= 3&&village.getLevel("build.php?id=21") >= 3&&village.emptySlots.Count > 0 && !village.buildBusy(checkBoxPlus.Checked))
                            {
                                Building emptySlot = (Building)village.emptySlots[0];
                                if (adapter.build(emptySlot.buildLink, 17))
                                {
                                    Console.WriteLine("Built market level 1");
                                }
                                else
                                {
                                    Console.WriteLine("Cannot build market level 1");
                                }
                                break;
                            }
                            break;
                        case 24:
                            Console.WriteLine("gold");
                            adapter.postGold50();
                            AutoTask();
                            break;
                    }
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.StackTrace);
            }
        }

        private void backgroundWorkerDoTask_DoWork(object sender, DoWorkEventArgs e)
        {
            TaskCheck taskCheck = (TaskCheck)e.Argument;
            Console.WriteLine(taskCheck.taskType);
            switch (taskCheck.taskType)
            {
                case 0://check hero
                    checkHero();
                    break;
                case 1://normal farm
                    normalFarm();
                    break;
                case 2://goldclub farm
                    newGoldClubFarm();
                    break;
                case 3://building
                    checkBuilding();
                    break;
                case 4://market
                    checkMarkets();
                    break;
                case 5://buy troops
                    buyTroops();
                    break;
                case 6://check raid score
                    checkRaidScore();
                    break;
                case 7://check raid score
                    checkScouts();
                    break;
                case 8:
                    AutoTask();
                    break;
                case 9:
                    checkParty();
                    break;
            }
            taskCheck.lastDone = DateTime.Now.Ticks;
        }

        private void backgroundWorkerDoTask_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            UpdateListViewTaskCheck();
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                if (tabControl1.SelectedTab.Name.Equals("tabPageBuilding"))
                {
                    try
                    {
                        UpdateListViewBuildingCurrent(village, villages[listViewVillage.SelectedItems[0].Index].detailedInfo);
                        UpdateListViewBuildingQueue(village);
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
            syncConfigAndForm();
            saveConfig();
            toolStripProgressBar1.Value = 0;
            toolStripStatusLabel1.Text = "Idle";
        }

        private void backgroundWorkerDoTask_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            toolStripProgressBar1.Value = e.ProgressPercentage;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (listViewFarmlist.SelectedItems.Count > 0)
            {
                config.farmlists.RemoveAt(listViewFarmlist.SelectedItems[0].Index);
                UpdateListViewFarmList();
                saveConfig();
            }
        }

        private void buttonSaveConfigHero_Click(object sender, EventArgs e)
        {
            try
            {
                config.heroVillageId = textBoxHeroVillageId.Text;
                config.heroSolo = checkBoxHeroSolo.Checked;
                config.heroSoloMinHealth = Convert.ToInt32(textBoxHeroSoloMinHealth.Text);
                config.heroAttackX = Convert.ToInt32(textBoxHeroAttackX.Text);
                config.heroAdventure = checkBoxHeroAdventure.Checked;
                config.heroClearWithTroop = checkBoxHeroClearWithTroop.Checked;
                config.heroClearMinHealth = Convert.ToInt32(textBoxHeroClearMinHealth.Text);
                config.heroTroopAttackX = Convert.ToInt32(textBoxHeroTroopAttackX.Text);
                config.heroUseInfantryDef = checkBoxHeroUseInfantryDef.Checked;
                config.autoAddFighting = checkBoxAutoAddFighting.Checked;
                if (config.heroClearWithTroop)
                {
                    try
                    {
                        string[] tmp = comboBoxheroTroopType.SelectedItem.ToString().Split('_');
                        Troop troop = new Troop();
                        troop.id = Convert.ToInt32(tmp[0]);
                        troop.name = tmp[1];
                        troop.attack = Convert.ToInt32(tmp[2]);
                        config.heroTroopType = troop;
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show("Must select a troop type to clear oasis with");
                    }
                }
                saveConfig();
            }
            catch (Exception ex)
            {
            }
        }

        private void buttonAddRoute_Click(object sender, EventArgs e)
        {
            try
            {
                Route route = new Route();
                Village from = config.getVillageByName(comboBoxRouteFrom.SelectedItem.ToString());
                route.fromId = from.id;
                route.fromName = from.name;
                Village to = config.getVillageByName(comboBoxRouteTo.Text);
                if (to != null)
                {
                    route.toId = to.id;
                    route.toName = to.name;
                }
                else
                {
                    route.toId = "";
                    route.toName = comboBoxRouteTo.Text;
                }
                route.fromObject = (comboBoxRouteObject.SelectedIndex == 0);
                route.value = Convert.ToInt32(textBoxRouteValue.Text);
                route.unitInPercentage = comboBoxRouteUnit.SelectedItem.Equals("%");
                route.lumber = checkBoxLumber.Checked;
                route.clay = checkBoxClay.Checked;
                route.iron = checkBoxIron.Checked;
                route.crop = checkBoxCrop.Checked;
                if (route.unitInPercentage && route.value >= 100)
                {
                    MessageBox.Show("Percentage cannot be over 99");
                }
                else
                {
                    config.routes.Add(route);
                    UpdateListViewRoutes();
                    saveConfig();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Check your fields");
            }
        }

        private void buttonDeleteRoute_Click(object sender, EventArgs e)
        {
            if (listViewRoutes.SelectedItems.Count > 0)
            {
                config.routes.RemoveAt(listViewRoutes.SelectedItems[0].Index);
                UpdateListViewRoutes();
                saveConfig();
            }
        }

        private void listViewBuildingCurrent_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                string name = listViewBuildingCurrent.SelectedItems[0].SubItems[0].Text;
                int level = Convert.ToInt32(listViewBuildingCurrent.SelectedItems[0].SubItems[1].Text);
                bool resField = listViewBuildingCurrent.SelectedItems[0].SubItems[3].Text.Equals("True");
                string buildLink = listViewBuildingCurrent.SelectedItems[0].SubItems[4].Text;
                Building building = new Building();
                building.name = name;
                building.level = Math.Max(level, village.getQueuedLevel(buildLink, level)) + 1;
                building.buildLink = buildLink;
                building.resField = resField;
                village.buildingQueues.Add(building);
                UpdateListViewBuildingCurrent(village, villages[listViewVillage.SelectedItems[0].Index].detailedInfo);
                UpdateListViewBuildingQueue(village);
                saveConfig();
            }
        }

        private void buttonMoveUp_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0 && listViewBuildingQueue.SelectedItems.Count > 0)
            {
                if (listViewBuildingQueue.SelectedItems[0].Index > 0)
                {
                    Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                    Building building = (Building)village.buildingQueues[listViewBuildingQueue.SelectedItems[0].Index];
                    Building upperBuilding = (Building)village.buildingQueues[listViewBuildingQueue.SelectedItems[0].Index - 1];
                    if (!building.buildLink.Equals(upperBuilding.buildLink))
                    {
                        village.buildingQueues[listViewBuildingQueue.SelectedItems[0].Index] = upperBuilding;
                        village.buildingQueues[listViewBuildingQueue.SelectedItems[0].Index - 1] = building;
                        UpdateListViewBuildingQueue(village);
                        saveConfig();
                    }
                }
            }
        }

        private void buttonMoveDown_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0 && listViewBuildingQueue.SelectedItems.Count > 0)
            {
                if (listViewBuildingQueue.SelectedItems[0].Index < listViewBuildingQueue.Items.Count - 1)
                {
                    Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                    Building building = (Building)village.buildingQueues[listViewBuildingQueue.SelectedItems[0].Index];
                    Building lowerBuilding = (Building)village.buildingQueues[listViewBuildingQueue.SelectedItems[0].Index + 1];
                    if (!building.buildLink.Equals(lowerBuilding.buildLink))
                    {
                        village.buildingQueues[listViewBuildingQueue.SelectedItems[0].Index] = lowerBuilding;
                        village.buildingQueues[listViewBuildingQueue.SelectedItems[0].Index + 1] = building;
                        UpdateListViewBuildingQueue(village);
                        saveConfig();
                    }
                }
            }
        }

        private void buttonDeleteBuilds_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0 && listViewBuildingQueue.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                village.buildingQueues.RemoveAt(listViewBuildingQueue.SelectedItems[0].Index);
                UpdateListViewBuildingQueue(village);
                UpdateListViewBuildingCurrent(village, villages[listViewVillage.SelectedItems[0].Index].detailedInfo);
                saveConfig();
            }
        }

        private void buttonClearBuilds_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                village.buildingQueues.Clear();
                UpdateListViewBuildingQueue(village);
                UpdateListViewBuildingCurrent(village, villages[listViewVillage.SelectedItems[0].Index].detailedInfo);
                saveConfig();
            }
        }

        private void buttonRefresh_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                updateListViewFarmTarget(village.zones);
                if (tabControl1.SelectedTab.Name.Equals("tabPageBuilding"))
                {
                    VillageInfo info = adapter.getVillageInfo(village.id);
                    villages[listViewVillage.SelectedItems[0].Index].detailedInfo = info;
                    UpdateListViewBuildingCurrent(village, villages[listViewVillage.SelectedItems[0].Index].detailedInfo);
                    UpdateListViewBuildingQueue(village);
                    labelStorage.Text = "Warehouse:" + info.maxStore+" Granary:"+info.maxCrop;
                }
            }
        }

        private void buttonAddtroop_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                if (comboBoxTroopTypeToNormalFarm.SelectedItem != null)
                {
                    try
                    {
                        string[] tmp = comboBoxTroopTypeToNormalFarm.SelectedItem.ToString().Split('_');
                        int id = Convert.ToInt32(tmp[0]);
                        string name = tmp[1];
                        int attack = Convert.ToInt32(tmp[2]);
                        Troop troop = new Troop();
                        troop.id = id;
                        troop.name = name;
                        troop.number_each_wave = Convert.ToInt32(textBoxNoEachWave.Text);
                        troop.xCleanOasis = Convert.ToDouble(textBoxXCleanOasis.Text);
                        troop.maxPop = Convert.ToInt32(textBoxMaxPopNormalFarm.Text);
                        village.troops.Add(troop);
                        updateListViewTroop(village.troops);
                        saveConfig();
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
            else
            {
                MessageBox.Show("Please select a village");
            }
        }

        private void buttonDeleteTroop_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                if (listViewTroopToNormalFarm.SelectedItems.Count > 0)
                {
                    village.troops.RemoveAt(listViewTroopToNormalFarm.SelectedItems[0].Index);
                    updateListViewTroop(village.troops);
                    saveConfig();
                }
            }
        }

        private void buttonAddTroopBuy_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                try
                {
                    string[] tmp = comboBoxTroopBuy.SelectedItem.ToString().Split('_');
                    int troopID = Convert.ToInt32(tmp[0]);
                    string troopName = tmp[1];
                    tmp = comboBoxTroopBuilding.SelectedItem.ToString().Split('_');
                    int buildingGID = Convert.ToInt32(tmp[0]);
                    string buildingName = tmp[1];
                    BuyTroop buyTroop = new BuyTroop();
                    buyTroop.buildingGID = buildingGID;
                    buyTroop.buildingName = buildingName;
                    buyTroop.troopID = troopID;
                    buyTroop.troopName = troopName;
                    buyTroop.maxQueueTime = Convert.ToInt32(textBoxMaxQueueTime.Text);
                    if (comboBoxItem.SelectedItem != null)
                    {
                        string item = comboBoxItem.SelectedItem.ToString();
                        buyTroop.item = item;
                    }
                    village.troopToBuy.Add(buyTroop);

                    UpdateListViewBuyTroop(village.troopToBuy);
                    saveConfig();
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.StackTrace);
                }
            }
            else
            {
                MessageBox.Show("Please select a village");
            }
        }

        private void buttonDeleteTroopBuy_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                if (listViewBuyTroop.SelectedItems.Count > 0)
                {
                    village.troopToBuy.RemoveAt(listViewBuyTroop.SelectedItems[0].Index);
                    UpdateListViewBuyTroop(village.troopToBuy);
                    saveConfig();
                }
            }
        }

        private void buttonDrawRaidStatistics_Click(object sender, EventArgs e)
        {
            try
            {
                string fileName = Util.getRaidFileName(config);
                StreamReader reader = new StreamReader(fileName);
                string line;
                ArrayList labels = new ArrayList();
                chartRaidStatistics.Series[0].Points.Clear();
                int previous = 0;
                while (!reader.EndOfStream)
                {
                    line = reader.ReadLine();
                    string[] tmp = line.Split(',');
                    int y = 0;
                    if (previous != 0)
                    {
                        int thisRaid = Convert.ToInt32(tmp[0]);
                        if (thisRaid >= previous)
                        {
                            y = Convert.ToInt32(tmp[0]) - previous;
                        }
                        else
                        {
                            y = thisRaid;
                        }
                    }
                    previous = Convert.ToInt32(tmp[0]);
                    long x = Convert.ToInt64(tmp[1]);
                    DataPoint point = new DataPoint();
                    point.YValues = new double[] { y };
                    point.AxisLabel = new DateTime(x).ToString();
                    chartRaidStatistics.Series[0].Points.Add(point);
                }
                chartRaidStatistics.Series[0].ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;
            }
            catch (Exception ex)
            {
                MessageBox.Show("No data");
            }
        }

        private void buttonAddCustomFarm_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                Zone zone = new Zone();
                zone.x = Convert.ToInt32(textBoxX.Text);
                zone.y = Convert.ToInt32(textBoxY.Text);
                zone.type = "village";
                zone.distance = Math.Sqrt((zone.x - village.x) * (zone.x - village.x) + (zone.y - village.y) * (zone.y - village.y));
                if (!village.zones.Contains(zone))
                {
                    village.zones.Add(zone);
                    zone.defend = int.MaxValue;
                    village.zones.Sort(new ZoneComparer());
                    updateListViewFarmTarget(village.zones);
                    saveConfig();
                }
            }
            else
            {
                MessageBox.Show("Please select a village");
            }
        }

        private void buttonAddScoutTarget_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                Zone zone = new Zone();
                zone.x = Convert.ToInt32(textBoxScoutX.Text);
                zone.y = Convert.ToInt32(textBoxScoutY.Text);
                zone.type = "village";
                zone.distance = Math.Sqrt((zone.x - village.x) * (zone.x - village.x) + (zone.y - village.y) * (zone.y - village.y));
                if (!village.scoutTargets.Contains(zone))
                {
                    village.scoutTargets.Add(zone);
                    village.scoutTargets.Sort(new ZoneComparer());
                    updateListViewScouts(village.scoutTargets);
                    saveConfig();
                }
            }
            else
            {
                MessageBox.Show("Please select a village");
            }
        }

        private void buttonDeleteScoutTarget_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                if (listViewScouts.SelectedItems.Count > 0)
                {
                    village.scoutTargets.RemoveAt(listViewScouts.SelectedItems[0].Index);
                    updateListViewScouts(village.scoutTargets);
                    saveConfig();
                }
            }
        }

        private void buttonDeleteAllScoutTarget_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                village.scoutTargets.Clear();
                updateListViewScouts(village.scoutTargets);
                saveConfig();
            }
        }

        private void checkBoxAutoUpResources_CheckedChanged(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                village.autoUpRes = checkBoxAutoUpResources.Checked;
                saveConfig();
            }
        }

        private void checkBoxAutoUpStorage_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void buttonReloadOasis_Click(object sender, EventArgs e)
        {
            saveConfig();
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                /*
                    foreach (Zone zone in village.zones)
                    {
                        int def = adapter.getOasisDefend(zone.x, zone.y, false);
                        zone.defend = def;
                    }
                 */
                updateListViewFarmTarget(village.zones);
            }
        }

        private void buttonGetDef_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                    foreach (Zone zone in village.zones)
                    {
                        int def = adapter.getOasisDefend(zone.x, zone.y, false);
                        zone.defend = def;
                    }
                updateListViewFarmTarget(village.zones);
                saveConfig();
            }
        }

        private void buttonSearchElephan_Click(object sender, EventArgs e)
        {
            listViewElephan.Items.Clear();
            backgroundWorkerSearhElephan.RunWorkerAsync();
            buttonSearchElephan.Enabled = false;
        }

        private void buttonSearchDelete_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                int x = Convert.ToInt32(textBoxRemoveX.Text);
                int y = Convert.ToInt32(textBoxRemoveY.Text);
                double radius = Convert.ToDouble(textBoxRemoveRadius.Text);
                for (int i = village.zones.Count - 1; i >= 0; i--)
                {
                    Zone zone = (Zone)village.zones[i];
                    if (Math.Sqrt((zone.x - x) * (zone.x - x) + (zone.y - y) * (zone.y - y)) < radius)
                    {
                        village.zones.RemoveAt(i);
                        Console.WriteLine("removed " + zone.getXY());
                    }
                }
                updateListViewFarmTarget(village.zones);
                saveConfig();
            }
        }

        private void notifyIcon1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            Show();
            this.WindowState = FormWindowState.Normal;
            notifyIcon1.Visible = false;
        }

        private void Main_SizeChanged(object sender, EventArgs e)
        {
            if (this.WindowState == FormWindowState.Minimized)//this code gets fired on every resize
            {                        //so we check if the form was minimized
                Hide();//hides the program on the taskbar
                notifyIcon1.Visible = true;//shows our tray icon
            }
        }

        private void buttonGenerate_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                adapter.getHalfVillageInfo(village.id);
                timerMassAttack.Enabled = true;
                n = Convert.ToInt32(textBoxNumber.Text);
                attacks = new int[n, 14];
                dataGrid1.DataSource = new Mommo.Data.ArrayDataView(attacks, new string[] { "Main wave?", "T1", "T2", "T3", "T4", "T5", "T6", "Ram", "Cata", "Chief", "Settler", "Hero", "Target1", "Target2" });
            }
        }

        private void buttonPrepare_Click(object sender, EventArgs e)
        {
            threads = adapter.prepareMassAttack(n, attacks, textBoxMassAttackX.Text, textBoxMassAttackY.Text);
            if (threads.Length > 0)
            {
                MessageBox.Show("All attacks ready");
            }
            else
            {
                MessageBox.Show("Error. Please try again");
            }
        }

        private void button2_Click_1(object sender, EventArgs e)
        {
            startPlan = true;
        }

        private void timerMassAttack_Tick(object sender, EventArgs e)
        {
            labelCurrentTime.Text = "Current time: " + DateTime.Now.Hour + ":" + DateTime.Now.Minute + ":" + DateTime.Now.Second;
            if (startPlan && textBoxH.Text == DateTime.Now.Hour.ToString() && textBoxM.Text == DateTime.Now.Minute.ToString() && textBoxS.Text == DateTime.Now.Second.ToString())
            {
                startPlan = false;
                int delay = Convert.ToInt32(textBoxMs.Text);
                adapter.launchMassAttack(threads, delay);
            }
        }

        private void buttonSendNow_Click(object sender, EventArgs e)
        {
            startPlan = false;
            int delay = Convert.ToInt32(textBoxMs.Text);
            adapter.launchMassAttack(threads, delay);
        }

        private void buttonViewRaidLog_Click(object sender, EventArgs e)
        {
            updateListViewRaidLog();
        }

        private void buttonSaveRaidInterval_Click(object sender, EventArgs e)
        {
            int raidInterval = Convert.ToInt32(textBoxRaidInterval.Text);
            config.raidInterval = raidInterval;
            saveConfig();
        }

        private void buttonAddNatar_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                String result = adapter.request(adapter.server + "spieler.php?uid=1");
                Util.writeStringToFile(result, "natar.html");
                String pattern = "<a href=\"(.+?)\">(.+?)</a>\\s+</td>\\s+<td class=\"oases\">\\s+</td>\\s+<td class=\"inhabitants\">\\s+(\\d+)\\s+</td>\\s+<td class=\"coords\">\\s+<a class=\"\" href=\"karte\\.php\\?x=(-?\\d+)&amp;y=(-?\\d+)\">";
                Regex re = new Regex(pattern);
                MatchCollection matches = re.Matches(result);
                double minDist = Convert.ToDouble(textBoxMinDist.Text);
                double maxDist = Convert.ToDouble(textBoxMaxDist.Text);
                for (int i = 0; i < matches.Count; i++)
                {
                    string name = matches[i].Groups[2].Value;
                    int pop = Convert.ToInt32(matches[i].Groups[3].Value);
                    int x = Convert.ToInt32(matches[i].Groups[4].Value);
                    int y = Convert.ToInt32(matches[i].Groups[5].Value);
                    //Console.WriteLine(name+" "+pop + "," + x + "," + y);
                    double dist = Math.Sqrt((village.x - x) * (village.x - x) + (village.y - y) * (village.y - y));
                    if (dist >= minDist && dist <= maxDist && (x != 0 || y != 0) && !name.Equals("WW Village"))
                    {
                        Zone zone = new Zone();
                        zone.x = x;
                        zone.y = y;
                        zone.distance = dist;
                        zone.defend = pop;
                        village.zones.Add(zone);
                    }
                }

                village.zones.Sort(new ZoneComparer());
                updateListViewFarmTarget(village.zones);
                saveConfig();
            }
            else
            {
                MessageBox.Show("Please select a village");
            }
        }

        private void buttonAddInactives_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                String result = textBoxInactiveParser.Text;
                Util.writeStringToFile(result, "inactives.html");
                String pattern = "\\( (-?\\d+)\\s*\\|\\s*(-?\\d+) \\)";
                Regex re = new Regex(pattern);
                MatchCollection matches = re.Matches(result);
                double minDist = Convert.ToDouble(textBoxMinDist.Text);
                double maxDist = Convert.ToDouble(textBoxMaxDist.Text);
                for (int i = 0; i < matches.Count; i++)
                {
                    int x = Convert.ToInt32(matches[i].Groups[1].Value);
                    int y = Convert.ToInt32(matches[i].Groups[2].Value);
                    double dist = Math.Sqrt((village.x - x) * (village.x - x) + (village.y - y) * (village.y - y));
                    Zone zone = new Zone();
                    zone.x = x;
                    zone.y = y;
                    zone.distance = dist;
                    if (zone.distance > minDist && zone.distance <= maxDist && !village.zones.Contains(zone))
                    {
                        village.zones.Add(zone);
                    }
                }
                village.zones.Sort(new ZoneComparer());
                updateListViewFarmTarget(village.zones);
                saveConfig();
            }
            else
            {
                MessageBox.Show("Please select a village");
            }
        }

        private void buttonSuggest_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                int totalTroop = Convert.ToInt32(textBoxTotalTroop.Text);
                double totalDist = 0;
                for (int i = 0; i < village.zones.Count; i++)
                {
                    Zone zone = (Zone)village.zones[i];
                    totalDist += zone.distance;
                }
                double troopPerDist = (double)totalTroop / totalDist;
                textBoxTroopNumberToFarmList.Text = troopPerDist.ToString();
            }
            else
            {
                MessageBox.Show("Please select a village");
            }
        }

        private void buttonSaveMarket_Click(object sender, EventArgs e)
        {
            int merchanCapacity = Convert.ToInt32(textBoxMerchanCapacity.Text);
            config.merchanCapacity = merchanCapacity;
            config.fullMerchan = checkBoxFullMerchan.Checked;
            saveConfig();
        }

        private void checkBoxAutoParty_CheckedChanged(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                village.autoParty = checkBoxAutoParty.Checked;
                saveConfig();
            }
        }

        private void listViewBuildingCurrent_MouseClick(object sender, MouseEventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0 && e.Button == MouseButtons.Right)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                panelUpBuilding.Show();
                panelUpBuilding.Location = new Point(e.Location.X+listViewBuildingCurrent.Location.X, e.Location.Y+listViewBuildingCurrent.Location.Y);
                string name = listViewBuildingCurrent.SelectedItems[0].SubItems[0].Text;
                int level = Convert.ToInt32(listViewBuildingCurrent.SelectedItems[0].SubItems[1].Text);
                bool resField = listViewBuildingCurrent.SelectedItems[0].SubItems[3].Text.Equals("True");
                string buildLink = listViewBuildingCurrent.SelectedItems[0].SubItems[4].Text;
                int currentLevel = Math.Max(level, village.getQueuedLevel(buildLink, level)) + 1;
                textBoxLevel.Text = currentLevel.ToString();
                saveConfig();
            }
        }

        private void buttonAddBuilding_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                string name = listViewBuildingCurrent.SelectedItems[0].SubItems[0].Text;
                int level = Convert.ToInt32(listViewBuildingCurrent.SelectedItems[0].SubItems[1].Text);
                bool resField = listViewBuildingCurrent.SelectedItems[0].SubItems[3].Text.Equals("True");
                string buildLink = listViewBuildingCurrent.SelectedItems[0].SubItems[4].Text;
                int currentLevel = Math.Max(level, village.getQueuedLevel(buildLink, level)) + 1;
                int uplevel = Convert.ToInt32(textBoxLevel.Text);
                for (int i = currentLevel; i <= uplevel; i++)
                {
                    Building building = new Building();
                    building.name = name;
                    building.level = i;
                    building.buildLink = buildLink;
                    building.resField = resField;
                    village.buildingQueues.Add(building);
                }
                UpdateListViewBuildingCurrent(village, villages[listViewVillage.SelectedItems[0].Index].detailedInfo);
                UpdateListViewBuildingQueue(village);
                saveConfig();
                panelUpBuilding.Hide();
            }

        }

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            panelUpBuilding.Hide();
        }

        private void buttonBid_Click(object sender, EventArgs e)
        {
            string link = textBoxLinkBidPage.Text;
            int price = Convert.ToInt32(textBoxPrice.Text);
            adapter.autoBid(link, price);
        }

        private void backgroundWorkerSearhElephan_DoWork(object sender, DoWorkEventArgs e)
        {
            int x = Convert.ToInt32(textBoxElephanX.Text);
            int y = Convert.ToInt32(textBoxElephanY.Text);
            string name = textBoxElephanName.Text;
            ArrayList allOasis = Util.DeSerializeArrayList("oasis.xml");
            for (int i = 0; i < allOasis.Count; i++)
            {
                Zone zone = (Zone)allOasis[i];
                zone.distance = Math.Sqrt((zone.x - x) * (zone.x - x) + (zone.y - y) * (zone.y - y));
            }
            allOasis.Sort(new ZoneComparer());
            for (int i = 0; i < allOasis.Count; i++)
            {
                
                    Zone zone = (Zone)allOasis[i];
                    if (adapter.has(zone.x, zone.y, name))
                    {
                        Console.WriteLine(zone.getXY());
                        AddResult(new string[] { zone.getXY(), zone.distance.ToString() });
                    }

                backgroundWorkerSearhElephan.ReportProgress(i * 100 / allOasis.Count);
            }
        }

        private void backgroundWorkerSearhElephan_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            progressBarSearchElephan.Value = e.ProgressPercentage;
        }

        private void backgroundWorkerSearhElephan_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            MessageBox.Show("Done searching");
            buttonSearchElephan.Enabled = true;
        }

        delegate void AddResultCallBack(string[] results);
        private void AddResult(string[] results)
        {
            if (this.listViewElephan.InvokeRequired)
            {
                AddResultCallBack d = new AddResultCallBack(AddResult);
                this.Invoke(d, new object[] { results });
            }
            else
            {
                listViewElephan.Items.Add(new ListViewItem(results));
            }
        }

        private void buttonLoadItem_Click(object sender, EventArgs e)
        {
            comboBoxItem.Items.Clear();
            HeroInfo heroInfo = adapter.getHeroInfo();
            foreach (Item item in heroInfo.equippedItems)
            {
                if (item.slot.Equals("helmet"))
                {
                    comboBoxItem.Items.Add(item.name);
                }
            }
            foreach (Item item in heroInfo.unequippedItems)
            {
                if (item.slot.Equals("helmet"))
                {
                    comboBoxItem.Items.Add(item.name);
                }
            }
        }

        private void buttonClearRoute_Click(object sender, EventArgs e)
        {
            config.routes.Clear();
            UpdateListViewRoutes();
            saveConfig();
        }

        private void checkBoxUseTor_CheckedChanged(object sender, EventArgs e)
        {
            config.useTor = checkBoxUseTor.Checked;
            Constants.useTor = config.useTor;
            saveConfig();
        }

        private void buttonToScout_Click(object sender, EventArgs e)
        {
            if (listViewVillage.SelectedItems.Count > 0)
            {
                Village village = (Village)config.villages[listViewVillage.SelectedItems[0].Index];
                foreach (Zone zone in village.zones)
                {
                    if (!village.scoutTargets.Contains(zone))
                    {
                        village.scoutTargets.Add(zone);
                        village.scoutTargets.Sort(new ZoneComparer());
                        updateListViewScouts(village.scoutTargets);
                    }
                }
                saveConfig();
            }
            else
            {
                MessageBox.Show("Please select a village");
            }
        }

    }

}
